<template>
  <div class="audio-choices">
    <div class="choices-grid">
      <div
        v-for="choice in choices"
        :key="choice.id"
        class="audio-card"
        :class="{
          selected: selectedId === choice.id,
          playing: playingId === choice.id,
          correct: showFeedback && choice.isCorrect,
          incorrect: showFeedback && selectedId === choice.id && !choice.isCorrect,
        }"
        @click="handleCardClick(choice)"
      >
        <div class="play-button">
          <el-icon :size="24">
            <video-play v-if="playingId !== choice.id" />
            <video-pause v-else />
          </el-icon>
        </div>

        <!-- 答案反馈图标 -->
        <div v-if="showFeedback" class="feedback-icon">
          <el-icon :size="24" v-if="choice.isCorrect" class="correct-icon">
            <circle-check-filled />
          </el-icon>
          <el-icon
            :size="24"
            v-if="selectedId === choice.id && !choice.isCorrect"
            class="incorrect-icon"
          >
            <circle-close-filled />
          </el-icon>
        </div>

        <div v-if="playingId === choice.id" class="wave-animation">
          <span></span>
          <span></span>
          <span></span>
          <span></span>
        </div>
      </div>
    </div>

    <!-- 检查按钮 -->
    <div class="check-button-container">
      <el-button type="primary" @click="checkAnswer" :disabled="!selectedId || showFeedback">
        检查答案
      </el-button>
    </div>

    <!-- 答案反馈提示 -->
    <div
      v-if="showFeedback"
      class="feedback-message"
      :class="isCorrectAnswer ? 'correct' : 'incorrect'"
    >
      <el-alert
        :title="feedbackMessage"
        :type="isCorrectAnswer ? 'success' : 'error'"
        :closable="false"
        show-icon
      />
    </div>
  </div>
</template>

<script setup lang="ts">
import { ref, onUnmounted, computed } from 'vue'
import {
  VideoPlay,
  VideoPause,
  CircleCheckFilled,
  CircleCloseFilled,
} from '@element-plus/icons-vue'
import axios from 'axios'
import { ElMessage } from 'element-plus'
import { base64ToBlob, createAudioElement, playAudio, cleanupAudio } from '@/utils/audioUtils'

interface AudioChoice {
  id: string
  audioUrl: string
  isCorrect: boolean
}

const props = defineProps<{
  choices: AudioChoice[]
}>()

const emit = defineEmits<{
  (e: 'select', choiceId: string): void
  (e: 'answer', correct: boolean): void
}>()

const selectedId = ref<string>('')
const playingId = ref<string>('')
const audioElement = ref<HTMLAudioElement | null>(null)
const isLoading = ref(false)
const showFeedback = ref(false)

// 计算是否答对
const isCorrectAnswer = computed(() => {
  if (!selectedId.value || !showFeedback.value) return false
  return props.choices.find((choice) => choice.id === selectedId.value)?.isCorrect || false
})

// 反馈消息
const feedbackMessage = computed(() => {
  if (!showFeedback.value) return ''
  return isCorrectAnswer.value ? '回答正确！' : '回答错误，请重试'
})

const handleCardClick = async (choice: AudioChoice) => {
  // 如果正在加载，不响应点击
  if (isLoading.value) return

  // 如果点击的是当前正在播放的音频，则停止播放
  if (playingId.value === choice.id) {
    if (audioElement.value) {
      cleanupAudio(audioElement.value)
      audioElement.value = null
    }
    playingId.value = ''
    return
  }

  // 停止当前播放的音频并清理资源
  if (audioElement.value) {
    cleanupAudio(audioElement.value)
    audioElement.value = null
  }

  try {
    isLoading.value = true

    // 获取音频的base64数据
    const response = await axios.post('/api/audio/base64?' + 'text=' + choice.audioUrl)

    const base64Audio = response.data
    const audioBlob = base64ToBlob(base64Audio, 'audio/mp3')
    const audioUrl = URL.createObjectURL(audioBlob)

    // 使用工具函数创建音频元素
    audioElement.value = await createAudioElement(audioUrl, {
      timeout: 10000,
    })

    // 开始播放
    await playAudio(audioElement.value)
    playingId.value = choice.id

    // 如果选择了新的选项，重置反馈状态
    if (selectedId.value !== choice.id) {
      selectedId.value = choice.id
      showFeedback.value = false
      emit('select', choice.id)
    }

    // 监听音频播放结束
    audioElement.value.onended = () => {
      playingId.value = ''
      if (audioElement.value) {
        cleanupAudio(audioElement.value, audioUrl)
        audioElement.value = null
      }
    }
  } catch (error) {
    console.error('音频播放失败:', error)
    ElMessage.error('音频播放失败，请稍后重试')

    // 清理资源
    if (audioElement.value) {
      cleanupAudio(audioElement.value)
      audioElement.value = null
    }
  } finally {
    isLoading.value = false
  }
}

// 检查答案
const checkAnswer = () => {
  if (!selectedId.value) return

  const selectedChoice = props.choices.find((choice) => choice.id === selectedId.value)
  if (!selectedChoice) return

  showFeedback.value = true
  emit('answer', selectedChoice.isCorrect)
}

// 组件卸载时清理音频资源
onUnmounted(() => {
  if (audioElement.value) {
    cleanupAudio(audioElement.value)
    audioElement.value = null
  }
})
</script>

<style scoped>
.audio-choices {
  width: 100%;
  max-width: 800px;
  margin: 0 auto;
  padding: 1rem;
}

.choices-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
  gap: 1rem;
  justify-content: center;
}

.audio-card {
  position: relative;
  height: 100px;
  background: white;
  border-radius: 8px;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
  cursor: pointer;
  transition: all 0.3s ease;
  display: flex;
  align-items: center;
  justify-content: center;
  overflow: hidden;
}

.audio-card:hover {
  transform: translateY(-2px);
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
}

.audio-card.selected {
  border: 2px solid #409eff;
  background: rgba(64, 158, 255, 0.05);
}

.audio-card.playing .play-button {
  color: #1890ff;
}

.play-button {
  color: #666;
  transition: color 0.3s ease;
}

.wave-animation {
  position: absolute;
  bottom: 10px;
  left: 0;
  right: 0;
  height: 20px;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 3px;
}

.wave-animation span {
  display: block;
  width: 3px;
  height: 100%;
  background-color: #1890ff;
  animation: wave 1s infinite ease-in-out;
}

.wave-animation span:nth-child(2) {
  animation-delay: 0.2s;
}
.wave-animation span:nth-child(3) {
  animation-delay: 0.4s;
}
.wave-animation span:nth-child(4) {
  animation-delay: 0.6s;
}

@keyframes wave {
  0%,
  100% {
    height: 8px;
  }
  50% {
    height: 20px;
  }
}

@media (max-width: 600px) {
  .choices-grid {
    grid-template-columns: 1fr;
    gap: 0.8rem;
  }

  .audio-card {
    height: 80px;
  }
}

.audio-card.correct {
  border: 2px solid #67c23a;
  background: rgba(103, 194, 58, 0.1);
}

.audio-card.incorrect {
  border: 2px solid #f56c6c;
  background: rgba(245, 108, 108, 0.1);
}

.feedback-icon {
  position: absolute;
  top: 8px;
  right: 8px;
}

.correct-icon {
  color: #67c23a;
}

.incorrect-icon {
  color: #f56c6c;
}

.feedback-message {
  margin-top: 16px;
}

.feedback-message.correct :deep(.el-alert) {
  background-color: #f0f9eb;
}

.feedback-message.incorrect :deep(.el-alert) {
  background-color: #fef0f0;
}

.check-button-container {
  display: flex;
  justify-content: center;
  margin-top: 1.5rem;
  margin-bottom: 1rem;
}
</style>
